<template>
  <div>
    <a-card>
      <a-space>
        <a-input
          v-model:value="listQuery.roleName"
          placeholder="输入条件搜索"
          allow-clear
          @keyup.enter="handleFilter"
        />
        <a-button type="primary" :icon="h(SearchOutlined)" @click="handleFilter">搜索</a-button>
      </a-space>
    </a-card>
    <a-card class="mt-2">
      <a-button type="primary" class="mb-4" :icon="h(PlusOutlined)" @click="handleAdd">
        添加
      </a-button>
      <a-table
        bordered
        :columns="columns"
        :data-source="data"
        :pagination="pagination"
        :loading="tableLoading"
        :row-key="(row) => row.roleId"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'actions'">
            <a-button size="small" type="link" @click="handleEdit(record)">编辑</a-button>
            <a-button size="small" type="link" danger @click="handleDelete(record)">删除</a-button>
          </template>
        </template>
      </a-table>
    </a-card>
    <a-modal v-model:open="showModal" :mask-closable="false" :title="title">
      <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" class="pt-1">
        <a-form-item label="角色名称" name="roleName">
          <a-input
            v-model:value="form.roleName"
            allow-clear
            show-count
            :maxlength="15"
            placeholder="请输入角色名称"
          />
        </a-form-item>
        <a-form-item label="显示顺序" name="roleSort">
          <a-input-number
            v-model:value="form.roleSort"
            allow-clear
            :precision="0"
            style="width: 100%"
            :max="2147483647"
            :min="-2147483648"
          />
        </a-form-item>
        <a-form-item label="菜单权限" name="menuIds">
          <div class="menu-tree">
            <a-tree
              v-model:checkedKeys="checkedKeys"
              blockNode
              checkable
              default-expand-all
              auto-expand-parent
              :check-strictly="true"
              :selectable="false"
              :tree-data="menuTree"
              :field-names="{
                title: 'menuName',
                key: 'menuId',
              }"
            />
          </div>
        </a-form-item>
      </a-form>
      <template #footer>
        <a-button @click="handleCheckedAll">全部{{ checkedAll ? '取消' : '选择' }}</a-button>
        <a-button type="primary" :loading="formBtnLoading" @click="handleConfirm">提交</a-button>
      </template>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
  import { h, onMounted, reactive, ref } from 'vue';
  import RoleApi from '@/api/RoleApi';
  import { PlusOutlined, SearchOutlined } from '@ant-design/icons-vue';
  import MenuApi from '@/api/MenuApi';
  import { message, Modal } from 'ant-design-vue';
  import { Rule } from 'ant-design-vue/es/form';
  import { resetReactive } from '@/utils';

  let columns = [
    { title: '角色名称', dataIndex: 'roleName' },
    { title: '显示顺序', dataIndex: 'roleSort' },
    { title: '创建时间', dataIndex: 'createTime' },
    { title: '更新时间', dataIndex: 'updateTime' },
    {
      title: '操作',
      dataIndex: 'actions',
      align: 'center',
    },
  ];
  let data = ref([]);
  const pagination = reactive({
    current: 1,
    pageSize: 10,
    total: 0,
    onChange: (current, pageSize) => {
      pagination.current = current;
      pagination.pageSize = pageSize;
      getList();
    },
  });
  onMounted(() => {
    getMenuTree();
    getList();
  });

  const listQuery = reactive<any>({});

  const tableLoading = ref(false);

  function getList() {
    tableLoading.value = true;
    RoleApi.page({ index: pagination.current, size: pagination.pageSize, ...listQuery })
      .then((res) => {
        data.value = res.data;
        pagination.total = res.total;
      })
      .finally(() => (tableLoading.value = false));
  }

  const menuTree = ref([]);
  const menuList = ref<Menu[]>([]);

  function getMenuTree() {
    MenuApi.listAndTree().then((res) => {
      menuTree.value = res.data[0]?.tree;
      menuList.value = res.data[0]?.list;
    });
  }

  function handleFilter() {
    pagination.current = 1;
    getList();
  }

  const showModal = ref(false);
  const title = ref('');
  const formRef = ref();
  const form = reactive<Role>({
    roleSort: 0,
    roleName: '',
  });
  const rules: Record<string, Rule[]> = {
    roleName: [{ required: true, trigger: 'blur', message: '请输入' }],
  };

  function handleEdit(row) {
    showModal.value = true;
    title.value = '编辑';
    Object.assign(form, row);
    formRef.value?.clearValidate();
    getChecked();
  }

  function getChecked() {
    RoleApi.checked(form.roleId).then((res) => {
      checkedKeys.value.checked = res.data;
    });
  }

  function handleAdd() {
    showModal.value = true;
    title.value = '添加';
    resetReactive(form);
    formRef.value?.clearValidate();
    checkedKeys.value = { checked: [] };
  }

  const formBtnLoading = ref(false);

  function handleConfirm() {
    formRef.value
      .validate()
      .then(() => {
        formBtnLoading.value = true;
        form.menuIds = checkedKeys.value.checked;
        (form.roleId ? RoleApi.update(form) : RoleApi.save(form))
          .then(() => {
            message.success('提交成功');
            showModal.value = false;
            getList();
          })
          .finally(() => {
            formBtnLoading.value = false;
          });
      })
      .catch(() => {});
  }

  function handleDelete(row) {
    Modal.confirm({
      title: '提示',
      content: '确定删除这条记录吗',
      okText: '确定',
      cancelText: '取消',
      onOk: () => {
        RoleApi.delete([row.roleId]).then(() => {
          message.success('操作成功');
          getList();
        });
      },
      onCancel: () => {},
    });
  }

  const checkedKeys = ref<{ checked: number[] }>({ checked: [] });
  const checkedAll = ref(false);

  function handleCheckedAll() {
    if (!checkedAll.value) {
      checkedKeys.value.checked = menuList.value?.map((i) => i.menuId);
      checkedAll.value = true;
    } else {
      checkedKeys.value = { checked: [] };
      checkedAll.value = false;
    }
  }
</script>

<style scoped>
  .menu-tree {
    border: 1px solid #e0e0e5;
    border-radius: 6px;
    max-height: 300px;
    min-height: 150px;
    width: 100%;
    overflow: auto;
  }
</style>
